package org.jeecg.modules.lottery.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.bid.entity.BidManagement;
import org.jeecg.modules.bid.service.IBidManagementService;
import org.jeecg.modules.lottery.Vo.LotteryManagementVo;
import org.jeecg.modules.lottery.dto.queryLotteryRequest;
import org.jeecg.modules.lottery.entity.Lottery;
import org.jeecg.modules.lottery.entity.LotteryManagement;
import org.jeecg.modules.lottery.service.ILotteryManagementService;
import org.jeecg.modules.lottery.service.ILotteryService;
import org.jeecg.modules.supplier.entity.Supplier;
import org.jeecg.modules.supplier.service.ISupplierService;
import org.jeecg.modules.supplierEvaluation.dto.SupplierEvaQueryRequest;
import org.jeecg.modules.supplierEvaluation.entity.SupplierEvaluation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "抽签管理22")
@RestController
@RequestMapping("/procurement/lottery")
@Slf4j
public class LotteryController extends JeecgController<Lottery, ILotteryService> {

    @Autowired
    private ILotteryService lotteryService;

    @Autowired
    private ILotteryManagementService lotteryManagementService;

    @Autowired
    private ISupplierService supplierService;

    @Autowired
    private IBidManagementService bidManagementService;

    @AutoLog(value = "抽签-分页列表查询")
    @ApiOperation(value = "抽签-分页列表查询", notes = "抽签-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(@RequestParam(defaultValue = "1") Integer pageNo,
                                   @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            Page<LotteryManagement> page = new Page<>(pageNo, pageSize);
            // 创建查询条件，添加按创建时间降序排序
            QueryWrapper<LotteryManagement> queryWrapper = new QueryWrapper<>();
            queryWrapper.orderByDesc("create_time");
            page = lotteryManagementService.page(page, queryWrapper);
            if (page.getTotal() == 0) {
                return Result.OK("未查询到抽签记录", page);
            }
            return Result.OK(page);
        } catch (Exception e) {
            log.error("查询抽签列表失败", e);
            return Result.error("查询失败，请稍后重试");
        }
    }

    @AutoLog(value = "抽签管理-执行抽签")
    @ApiOperation(value = "抽签管理-执行抽签", notes = "抽签管理-执行抽签")
    @PostMapping(value = "/conduct")
    public Result<?> conductLottery(@RequestParam String Id,
                                    @RequestParam String purchaseId,
                                    @RequestParam(required = false) String category,
                                    @RequestParam(defaultValue = "5") int drawCount) {
        try {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            List<Lottery> results = lotteryService.conductLottery(Id,purchaseId, category, drawCount, sysUser.getUsername());
            //抽完签，新建BidManagement
            bidManagementService.createBidManagementFromPurchase(purchaseId);

            return Result.OK("抽签成功！", results);
        } catch (Exception e) {
            log.error("抽签失败：" + e.getMessage(), e);
            return Result.error("抽签失败：" + e.getMessage());
        }
    }

    @AutoLog(value = "抽签管理-二次补抽")
    @ApiOperation(value = "抽签管理-二次补抽", notes = "抽签管理-二次补抽")
    @PostMapping(value = "/supplement")
    public Result<?> conductSupplementaryLottery(@RequestParam String Id,
                                                 @RequestParam String purchaseId,
                                                 @RequestParam(required = false) String category,
                                                 @RequestParam int supplementCount) {
        try {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            List<Lottery> results = lotteryService.conductSupplementaryLottery(Id,purchaseId , category, supplementCount, sysUser.getUsername());

            return Result.OK("补抽成功！", results);
        } catch (Exception e) {
            log.error("补抽失败：" + e.getMessage(), e);
            return Result.error("补抽失败：" + e.getMessage());
        }
    }

    @AutoLog(value = "抽签管理-放弃抽签")
    @ApiOperation(value = "抽签管理-放弃抽签", notes = "抽签管理-放弃抽签")
    @PostMapping(value = "/abandon")//TODO 存在问题
    public Result<?> abandonLottery(@RequestParam String lotteryId, @RequestParam String remark) {
        try {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            boolean success = lotteryService.abandonLottery(lotteryId, sysUser.getUsername(),remark);
            if (success) {
                return Result.OK("放弃抽签成功！");
            }

        } catch (Exception e) {
            log.error("放弃抽签失败：" + e.getMessage(), e);
            return Result.error("放弃抽签失败：" + e.getMessage());
        }
        return Result.error("放弃抽签失败！");
    }

    @AutoLog(value = "抽签管理-获取抽签结果")
    @ApiOperation(value = "抽签管理-获取抽签结果列表", notes = "抽签管理-获取抽签结果")
    @GetMapping(value = "/results")
    public Result<?> getLotteryResults(@RequestParam String lotteryStatus) {
        List<Lottery> results = lotteryService.getLotteryResults(lotteryStatus);
        return Result.OK(results);
    }

    //通过id查询
    @AutoLog(value = "抽签管理-通过id查询")
    @ApiOperation(value = "抽签管理-通过id查询", notes = "抽签管理-通过id查询")
    @GetMapping(value = "/{Id}")
    public Result<?> getLotteryById(@PathVariable String Id) {
        LotteryManagement lotteryManagement = lotteryManagementService.getById(Id);
        if (lotteryManagement != null) {
            LotteryManagementVo lotteryManagementVo = new LotteryManagementVo();
            BeanUtils.copyProperties(lotteryManagement, lotteryManagementVo);

            // 参加抽签的列表
            if (Objects.equals(lotteryManagement.getStatus(), "1")) {
                List<Supplier> supplierRecords = supplierService.getSuppliersForLottery(lotteryManagement.getCategory());

                // 解析中签供应商名称（使用中文逗号“,”分割）
                Set<String> winningSupplierNames = new HashSet<>();
                String winningSuppliersStr = lotteryManagement.getWinningSuppliers();
                if (StringUtils.isNotBlank(winningSuppliersStr)) {
                    // 注意：这里用的是英文逗号 ","
                    winningSupplierNames = Arrays.stream(winningSuppliersStr.split(","))
                            .map(String::trim)
                            .filter(s -> !s.isEmpty())
                            .collect(Collectors.toSet());
                }

                // 排序：中签的排在前面（根据 Supplier.getCompanyName() 判断）
                Set<String> finalWinningSupplierNames = winningSupplierNames;
                supplierRecords.sort((s1, s2) -> {
                    String name1 = s1.getCompanyName(); //
                    String name2 = s2.getCompanyName();

                    boolean isS1Winning = finalWinningSupplierNames.contains(name1);
                    boolean isS2Winning = finalWinningSupplierNames.contains(name2);

                    if (isS1Winning && !isS2Winning) {
                        return -1; // s1 在前
                    } else if (!isS1Winning && isS2Winning) {
                        return 1;  // s2 在前
                    } else {
                        return 0;  // 同类，保持原顺序（或可扩展二次排序）
                    }
                });

                lotteryManagementVo.setParticipants(supplierRecords);
            }
            return Result.OK(lotteryManagementVo);
        } else {
            return Result.error("未找到该抽签记录！");
        }
    }

    //通过purchaseId查询抽签记录proc_lottery表
//    @AutoLog(value = "抽签管理-通过purchaseId查询抽签记录")
//    @ApiOperation(value = "抽签管理-通过purchaseId查询抽签记录", notes = "抽签管理-通过purchaseId查询抽签记录")
    @GetMapping(value = "/records")
    public Result<?> getLotteryRecordsByPurchaseId(@RequestParam String purchaseId,String lotteryStatus) {
        try {
            // 使用QueryWrapper根据purchaseId查询抽签记录
            List<Lottery> lotteryRecords = lotteryService.getLotteryResultsByStatusAndPurchaseId(lotteryStatus, purchaseId);
            return Result.OK(lotteryRecords);
        } catch (Exception e) {
            log.error("查询抽签记录失败：" + e.getMessage(), e);
            return Result.error("查询抽签记录失败：" + e.getMessage());
        }
    }


    //中签的供应商列表，用逗号合并供应商名字companyName存在proc_lottery_management表的 winningSuppliers字段中
    @AutoLog(value = "抽签管理-获取中签供应商列表")
    @ApiOperation(value = "抽签管理-获取中签供应商列表", notes = "抽签管理-获取中签供应商列表")
    @GetMapping(value = "/winning-suppliers")
    public Result<?> getWinningSuppliers(@RequestParam String purchaseId) {
        try {
            // 调用service层方法获取合并后的中签供应商名称
            String winningSupplierNames = lotteryService.getWinningSupplierNamesByPurchaseId(purchaseId);

            // 如果没有记录，返回提示信息
            if (winningSupplierNames.isEmpty()) {
                return Result.OK("暂无中签供应商记录");
            }

            return Result.OK(winningSupplierNames);
        } catch (Exception e) {
            log.error("获取中签供应商列表失败：" + e.getMessage(), e);
            return Result.error("获取中签供应商列表失败：" + e.getMessage());
        }
    }
    //添加接口
    @AutoLog(value = "抽签管理-添加")
    @ApiOperation(value = "抽签管理-添加", notes = "抽签管理-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestParam String purchaseId,String category) {
        try {
            lotteryManagementService.add(purchaseId,category);
            //TODO 抽签前要展示参与抽签的供应商吗？
            return Result.OK("添加成功！");
        } catch (Exception e) {
            log.error("添加失败：" + e.getMessage(), e);
            return Result.error("添加失败：" + e.getMessage());
        }
    }


    //传入id和companyName.：根据id查询proc_lottery_management表格，查看字段winningSuppliers（已经用逗号分割），并要去掉传入的companyName.
//    @AutoLog(value = "抽签管理-去掉中签供应商")
//    @ApiOperation(value = "抽签管理-去掉中签供应商", notes = "抽签管理-去掉中签供应商")
//    @GetMapping(value = "/remove-winning-supplier")
    public Result<?> removeWinningSupplier(@RequestParam String lotteryId, @RequestParam String companyName) {
        try {
            // 调用service层方法去掉中签供应商
            boolean success = lotteryService.removeWinningSupplier(lotteryId, companyName);

            if (success) {
                return Result.OK("去掉中签供应商成功！");
            } else {
                return Result.error("去掉中签供应商失败！");
            }
        } catch (Exception e) {
            log.error("去掉中签供应商失败：" + e.getMessage(), e);
            return Result.error("去掉中签供应商失败：" + e.getMessage());
        }
    }
    //导出通过ids查询LotteryManagement，导出excel，导出多条
    @AutoLog(value = "抽签管理-导出Excel")
    @ApiOperation(value = "抽签管理-导出Excel", notes = "抽签管理-导出Excel")
    @GetMapping(value = "/exportExcelById")
    public void exportExcelById(@RequestParam List<String> ids, HttpServletRequest request, HttpServletResponse response) {
        log.info("收到Excel导出请求，ids数量: {}", ids != null ? ids.size() : 0);
        try {
            // 验证参数
            if (ids == null || ids.isEmpty()) {
                log.warn("导出Excel失败: ids参数为空");
                // 设置正确的响应头
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment;filename=error.xlsx");
                response.setCharacterEncoding("UTF-8");

                // 创建一个简单的错误信息Excel文件
                XSSFWorkbook errorWorkbook = null;
                ServletOutputStream errorOutputStream = null;
                try {
                    errorWorkbook = new XSSFWorkbook();
                    XSSFSheet sheet = errorWorkbook.createSheet("错误信息");
                    XSSFRow row = sheet.createRow(0);
                    row.createCell(0).setCellValue("导出Excel失败: 请选择要导出的记录");

                    errorOutputStream = response.getOutputStream();
                    errorWorkbook.write(errorOutputStream);
                    errorOutputStream.flush();
                    response.flushBuffer();
                } finally {
                    if (errorWorkbook != null) try { errorWorkbook.close(); } catch (Exception e) {}
                    if (errorOutputStream != null) try { errorOutputStream.close(); } catch (Exception e) {}
                }
                return;
            }

            // 设置响应头，确保不会被缓存
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);

            // 调用服务层方法导出Excel
            lotteryManagementService.exportExcelById(ids, request, response);
            log.info("Excel导出成功");
        } catch (Exception e) {
            log.error("导出Excel失败: " + e.getMessage(), e);
            // 重置响应，创建错误信息Excel文件
            try {
                response.reset();
                // 设置正确的响应头
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment;filename=error.xlsx");
                response.setCharacterEncoding("UTF-8");

                // 创建一个简单的错误信息Excel文件
                XSSFWorkbook errorWorkbook = null;
                ServletOutputStream errorOutputStream = null;
                try {
                    errorWorkbook = new XSSFWorkbook();
                    XSSFSheet sheet = errorWorkbook.createSheet("错误信息");
                    XSSFRow row = sheet.createRow(0);
                    row.createCell(0).setCellValue("导出Excel失败: " + e.getMessage());

                    errorOutputStream = response.getOutputStream();
                    errorWorkbook.write(errorOutputStream);
                    errorOutputStream.flush();
                    response.flushBuffer();
                } finally {
                    if (errorWorkbook != null) try { errorWorkbook.close(); } catch (Exception ew) {}
                    if (errorOutputStream != null) try { errorOutputStream.close(); } catch (Exception eo) {}
                }
            } catch (IOException ioException) {
                log.error("写入错误信息失败", ioException);
            }
        }
    }

    @AutoLog(value = "抽签管理-模糊查询")
    @ApiOperation(value = "抽签管理-模糊查询", notes = "抽签管理-模糊查询")
    @GetMapping(value = "/getLotteryBysearch")
    public Result<?> getLotteryBysearch(queryLotteryRequest queryRequest) {
        // 如果queryRequest为null，创建默认实例
        if (queryRequest == null) {
            queryRequest = new queryLotteryRequest();
        }
        // 设置默认分页参数
        if (queryRequest.getPageNum() == null || queryRequest.getPageNum() <= 0) {
            queryRequest.setPageNum(1);
        }
        if (queryRequest.getPageSize() == null || queryRequest.getPageSize() <= 0) {
            queryRequest.setPageSize(10);
        }
        // 创建查询条件
        Page<LotteryManagement> page = new Page<>(queryRequest.getPageNum(), queryRequest.getPageSize());
        QueryWrapper<LotteryManagement> queryWrapper = new QueryWrapper<>();
        //使用抽签状态模糊查询
        if(queryRequest.getProjectName()!=null && !queryRequest.getProjectName().isEmpty()){
            queryWrapper.like("project_name", queryRequest.getProjectName());
        }
        //使用项目名称模糊查询
        if(queryRequest.getStatus()!=null && !queryRequest.getStatus().isEmpty()){
            queryWrapper.eq("status", queryRequest.getStatus());
        }
        // 按创建时间倒序排列
        queryWrapper.orderByDesc("create_time");
        try {
            Page<LotteryManagement> LotteryPageList = lotteryManagementService.page(page, queryWrapper);
            if (page.getTotal() == 0){
                return Result.OK("未查询到符合条件的抽签记录", LotteryPageList);
            }
            return Result.OK(LotteryPageList);
        }catch (Exception e) {
            log.error("查询抽签记录失败", e);
            return Result.error("查询抽签记录失败：" + e.getMessage());
        }
    }
}
